/*
 * SearchInterface.java
 *
 * Created on 26 novembre 2012, 22:15
 */
package com.prototype.vaadin;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.*;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
 * @author Cmd
 * @version
 */

public class SearchInterface {
    /**.
     * @param appPath
     */
    private String appPath;
    /**.
     * @param comboDtYearStart
     */
    private ComboBox comboDtYearStart;
    /**.
     * @param comboDtYearEnd
     */
    private ComboBox comboDtYearEnd;
    /**.
     * @param comboDtUpdateStart
     */
    private ComboBox comboDtUpdateStart;
    /**.
     * @param comboDtUpdateEnd
     */
    private ComboBox comboDtUpdateEnd;
    /**@param formRecoverSf
     */
    private Form formRecoverSf;
    /**.
     * @param twinColCategories .
     */
    private TwinColumnSelect twinColCategories;
    /**.
     * @param twinColLicenses
     */
    private TwinColumnSelect twinColLicenses;
    /**.
     * @param twinColOs
     */
    private TwinColumnSelect twinColOs;
    /**.
     * @param nbDeveloper
     */
    private String nbDeveloperL;
    /**.
     * @param topDownload
     */
    private String topDownloadL;
    /**.
     * @param topLineCode
     */
    private String topLineCodeL;
    /**.
     * @param nbLinesCode
     */
    private String nbLinesCodeL;
    /**.
     * @param projectSize
     */
    private String projectSizeL;

    /**.
     * Define the year to start the combobox. if you choose 2000, it means that
     * the user will be able to choose a year between 2000 and the current year
     * @param YEARSTART
     */
    private static final int YEARSTART = 2000;
    /**.
     * Define the size of the combobox
     * @param COMBOSIZE
     */
    private static final int COMBOSIZE = 60;
    /**.
     * Define the width of the gridlayout
     * @param GRIDLAYOUTWIDTH
     */
    private static final int GRIDLAYOUTWIDTH = 100;
    /**.
     * @param GRIDLAYOUTNBROWS
     */
    private static final int GRIDLAYOUTNBROWS = 100;
    /**.
     * Define the number of columns of the gridlayout
     * @param GRIDLAYOUTNBCOLS
     */
    private static final int GRIDLAYOUTROW1 = 3;
     /**.
     * Define the number of rows of the gridlayout
     * @param GRIDLAYOUTNBCOLS
     */
    private static final int GRIDLAYOUTROW2 = 3;

    /**.
     * Constructor
     */
    public SearchInterface() {
        this.nbDeveloperL = "nb_developer";
        this.topDownloadL = "top_download";
        this.topLineCodeL = "top_line_code";
        this.nbLinesCodeL = "nb_lines_code";
        this.projectSizeL = "project_size";
    }

    /**.
     * @return app_path
     */
    public String getAppPath() {
        return appPath;
    }

    /**.
     * @param appPath
     */
    public void setAppPath(String appPath) {
        this.appPath = appPath;
    }

    /**.
     * Add combobox in a horizontal layout
     * @param prop
     * @return horizonLaytYear
     */
    public HorizontalLayout addCombo(AppProperties prop) {
        formRecoverSf = new Form();
        formRecoverSf.setDescription("");
        formRecoverSf.setWidth("400");
        comboDtYearStart = new ComboBox(prop.getPropValue(
                    "combo_dt_year_start"));
        comboDtYearEnd = new ComboBox(prop.getPropValue(
                    "combo_dt_year_end"));
        comboDtUpdateStart = new ComboBox(prop.getPropValue(
                    "combo_dt_update_start"));
        comboDtUpdateEnd = new ComboBox(prop.getPropValue(
                    "combo_dt_update_end"));
        comboDtYearStart.setWidth(COMBOSIZE, Sizeable.UNITS_PIXELS);
        comboDtYearEnd.setWidth(COMBOSIZE, Sizeable.UNITS_PIXELS);
        comboDtUpdateStart.setWidth(COMBOSIZE, Sizeable.UNITS_PIXELS);
        comboDtUpdateEnd.setWidth(COMBOSIZE, Sizeable.UNITS_PIXELS);
        Calendar calendrier;
        calendrier = Calendar.getInstance();
        for (int i = YEARSTART; i <= calendrier.get(Calendar.YEAR); i++) {
            comboDtYearStart.addItem(i);
            comboDtYearEnd.addItem(i);
            comboDtUpdateStart.addItem(i);
            comboDtUpdateEnd.addItem(i);
        }
        HorizontalLayout horizonLaytYear = new HorizontalLayout();
        horizonLaytYear.addComponent(comboDtYearStart);
        horizonLaytYear.addComponent(comboDtYearEnd);
        horizonLaytYear.addComponent(comboDtUpdateStart);
        horizonLaytYear.addComponent(comboDtUpdateEnd);
        horizonLaytYear.setMargin(true);
        horizonLaytYear.setSpacing(true);

        return horizonLaytYear;
    }

    /**.
     * Add os item in a twinColumn
     * @param prop
     * @param menuitems
     */
    public void createOs(AppProperties prop, Elements menuitems) {
        Iterator<Element> iterator = menuitems.iterator();
        twinColOs = new TwinColumnSelect();
        while (iterator.hasNext()) {
            Element item = iterator.next();
            if (item.html().substring(0, 2).equals("OS")) {
                Elements oslist = new Elements();
                for (int i = 0; i < item.parent().select("ul li span").
                        size(); i++) {
                    if ("ui-icon ui-icon-triangle-1-e".equals(
                    item.parent().select("ul li span").
                    get(i).attr("class"))) {
                        oslist.add(item.parent().select(
                        "ul li ul li a").get(i));
                    } else {
                        oslist.add(item.parent().select("ul li a").get(i));
                    }
                }
                twinColOs = new TwinColumnSelect(oslist);
                twinColOs.setCaption(prop.getPropValue("twinCol_os"));
            }
        }
    }

     /**.
      *
      * @param vlayoutSearchinterface
      * @throws IOException
      */
    public void recoverForm(VerticalLayout vlayoutSearchinterface)
            throws IOException {
            // Recovering properties file
            AppProperties prop = new AppProperties(appPath + File.separator
                    + "recover_sf_code2" + File.separator
                    + "web" + File.separator + "WEB-INF" + File.separator
                    + "french_label.properties");

            // Create and initialize the differents objects of the page
            Label lblDescription = new Label("<center>" + " "
                    + prop.getPropValue("app_description") + "<center>");
            lblDescription.setContentMode(Label.CONTENT_XHTML);
            // Create the main form
            HorizontalLayout horizonLaytYear = addCombo(prop);
            // Add a field and bind it to an named item property
            formRecoverSf.addField(nbDeveloperL, new TextField(
                    prop.getPropValue(nbDeveloperL)));
            formRecoverSf.addField(topDownloadL, new TextField(
                    prop.getPropValue(topDownloadL)));
            formRecoverSf.addField(topLineCodeL, new TextField(
                    prop.getPropValue(topLineCodeL)));
            formRecoverSf.addField(nbLinesCodeL, new TextField(
                    prop.getPropValue(nbLinesCodeL)));
            formRecoverSf.addField(projectSizeL, new TextField(
                    prop.getPropValue(projectSizeL)));
            VerticalLayout verticalLayt = new VerticalLayout();
            verticalLayt.addComponent(horizonLaytYear);
            verticalLayt.addComponent(formRecoverSf);
            verticalLayt.setMargin(true);
            verticalLayt.setSpacing(true);

            // Recover SF data
            // Categories
            AppProperties propSf = new AppProperties(appPath + File.separator
                    + "recover_sf_code2" + File.separator
                    + "web" + File.separator + "WEB-INF" + File.separator
                    + "sf_data.properties");

            Document sfPage = Jsoup.connect(propSf.getPropValue(
                    "sf_index")).timeout(0).get();
            Elements menuitems = sfPage.select("#metacats li a");
            twinColCategories = new TwinColumnSelect(menuitems);
            twinColCategories.setCaption(
                    prop.getPropValue("twinCol_categories"));
            // Licenses
            sfPage = Jsoup.connect(propSf.getPropValue("sf_criteria_page")).
                    timeout(0).get();
            menuitems = sfPage.select("div .facet header");
            Iterator<Element> iterator = menuitems.iterator();
            twinColLicenses = new TwinColumnSelect();
            while (iterator.hasNext()) {
                Element item = iterator.next();
                final int endSubString = 7;
                if (item.html().substring(0, endSubString).equals("License")) {
                    twinColLicenses = new TwinColumnSelect(item.parent().
                            select("ul li ul li a"));
                    twinColLicenses.setCaption(prop.getPropValue(
                            "twinCol_license"));
                }
            }

            // OS
            createOs(prop, menuitems);
            Button commitSearch = new Button(
                    prop.getPropValue("commit_search"));
            commitSearch.addListener(Button.ClickEvent.class, this, "show");

            // placement of objects in the page
            GridLayout gridLayoutMain = new GridLayout(2, GRIDLAYOUTNBROWS);
            gridLayoutMain.setStyleName("gridLayoutMain");
            gridLayoutMain.setWidth(GRIDLAYOUTWIDTH, Sizeable.UNITS_PERCENTAGE);
            gridLayoutMain.addComponent(twinColCategories, 0, 0);
            gridLayoutMain.addComponent(twinColLicenses, 0, 1);
            gridLayoutMain.addComponent(twinColOs, 0, 2);
            gridLayoutMain.addComponent(verticalLayt, 1, 0, 1, 2);
            gridLayoutMain.addComponent(commitSearch, 0, GRIDLAYOUTROW1, 1,
                    GRIDLAYOUTROW2);

            //objects positionnement
            gridLayoutMain.setComponentAlignment(commitSearch,
                    Alignment.TOP_CENTER);
            gridLayoutMain.setComponentAlignment(verticalLayt,
                    Alignment.TOP_CENTER);
            gridLayoutMain.setMargin(true);
            gridLayoutMain.setSpacing(true);
            vlayoutSearchinterface.addComponent(lblDescription);
            vlayoutSearchinterface.addComponent(gridLayoutMain);
    }

    /**.
     * Add the different values to the map li
     * @param li
     */
    public void addValue (Map li) {
        if (twinColCategories.toString() != null) {
            li.put("twinCol_categories", twinColCategories.getSelected());
        }
        if (twinColLicenses.toString() != null) {
            li.put("twinCol_licenses", twinColLicenses.getSelected());
        }
        if (twinColOs.toString() != null) {
            li.put("twinCol_os", twinColOs.getSelected());
        }
        if (comboDtYearStart.toString() != null) {
            li.put("combo_dt_year_start", comboDtYearStart.getValue().
                    toString());
        }
        if (comboDtYearEnd.toString() != null) {
            li.put("combo_dt_year_end", comboDtYearEnd.getValue().
                    toString());
        }
        if (comboDtUpdateStart.toString() != null) {
            li.put("comboDtUpdateStart", comboDtUpdateStart.getValue().
                    toString());
        }
        if (comboDtUpdateEnd.toString() != null) {
            li.put("combo_dt_update_end", comboDtUpdateEnd.getValue().
                    toString());
        }

    }
    /**.
     * recovery of input fields
     * @return li
     */
    public Map formRecover() {
        HashMap<String, String> li = new HashMap<String, String>();
        addValue(li);
        String nbDeveloper = formRecoverSf.getField(nbDeveloperL).toString();
        if (nbDeveloper.length() != 0) {
            li.put(nbDeveloper, nbDeveloper);
        }
        String topDownload = formRecoverSf.getField(topDownloadL).toString();
        if (topDownload.length() != 0) {
            li.put(topDownload, topDownload);
        }
        String topLineCode  = formRecoverSf.getField(topLineCodeL)
                .toString();
        if (topLineCode.length() != 0) {
            li.put(topLineCode, topLineCode);
        }
        String nbLinesCode = formRecoverSf.getField(nbLinesCodeL).toString();
        if ((nbLinesCode.length()) != 0) {
            li.put(nbLinesCode, nbLinesCode);
        }
        String projectSize = formRecoverSf.getField(projectSizeL).toString();
        if (projectSize.length() != 0) {
            li.put(projectSize, projectSize);
        }
        return li;
    }

    /**.
     * @param event
     */
    public void show(Button.ClickEvent event) {
        formRecoverSf.commit();
    }
}
